home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1995 April / Internet Tools.iso / infoserv / www / cern / doc / www-talk.archive.Z / www-talk.archive / text0393.txt < prev    next >
Encoding:
Text File  |  1992-11-30  |  8.5 KB  |  301 lines

  1. /*
  2. Copyright (c) 1991 Bell Communications Research, Inc. (Bellcore)
  3.  
  4. Permission to use, copy, modify, and distribute this material 
  5. for any purpose and without fee is hereby granted, provided 
  6. that the above copyright notice and this permission notice 
  7. appear in all copies, and that the name of Bellcore not be 
  8. used in advertising or publicity pertaining to this 
  9. material without the specific, prior written permission 
  10. of an authorized representative of Bellcore.  BELLCORE 
  11. MAKES NO REPRESENTATIONS ABOUT THE ACCURACY OR SUITABILITY 
  12. OF THIS MATERIAL FOR ANY PURPOSE.  IT IS PROVIDED "AS IS", 
  13. WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
  14. */
  15. #include <stdio.h>
  16. #include <ctype.h>
  17. #include <config.h>
  18.  
  19. extern char *index();
  20. static char basis_64[] =
  21.    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  22.  
  23. static char index_64[128] = {
  24.     -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
  25.     -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
  26.     -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63,
  27.     52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1,-1,-1,-1,
  28.     -1, 0, 1, 2,  3, 4, 5, 6,  7, 8, 9,10, 11,12,13,14,
  29.     15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1,
  30.     -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
  31.     41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1
  32. };
  33.  
  34. #define char64(c)  (((c) < 0 || (c) > 127) ? -1 : index_64[(c)])
  35.  
  36. /*
  37. char64(c)
  38. char c;
  39. {
  40.     char *s = (char *) index(basis_64, c);
  41.     if (s) return(s-basis_64);
  42.     return(-1);
  43. }
  44. */
  45.  
  46. to64(infile, outfile) 
  47. FILE *infile, *outfile;
  48. {
  49.     int c1, c2, c3, ct=0;
  50.     while ((c1 = getc(infile)) != EOF) {
  51.         c2 = getc(infile);
  52.         if (c2 == EOF) {
  53.             output64chunk(c1, 0, 0, 2, outfile);
  54.         } else {
  55.             c3 = getc(infile);
  56.             if (c3 == EOF) {
  57.                 output64chunk(c1, c2, 0, 1, outfile);
  58.             } else {
  59.                 output64chunk(c1, c2, c3, 0, outfile);
  60.             }
  61.         }
  62.         ct += 4;
  63.         if (ct > 71) {
  64.             putc('\n', outfile);
  65.             ct = 0;
  66.         }
  67.     }
  68.     if (ct) putc('\n', outfile);
  69.     fflush(outfile);
  70. }
  71.  
  72. output64chunk(c1, c2, c3, pads, outfile)
  73. FILE *outfile;
  74. {
  75.     putc(basis_64[c1>>2], outfile);
  76.     putc(basis_64[((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4)], outfile);
  77.     if (pads == 2) {
  78.         putc('=', outfile);
  79.         putc('=', outfile);
  80.     } else if (pads) {
  81.         putc(basis_64[((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6)], outfile);
  82.         putc('=', outfile);
  83.     } else {
  84.         putc(basis_64[((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6)], outfile);
  85.         putc(basis_64[c3 & 0x3F], outfile);
  86.     }
  87. }
  88.  
  89. PendingBoundary(s, Boundaries, BoundaryCt)
  90. char *s;
  91. char **Boundaries;
  92. int *BoundaryCt;
  93. {
  94.     int i;
  95.  
  96.     for (i=0; i < *BoundaryCt; ++i) {
  97.         if (!strncmp(s, Boundaries[i], strlen(Boundaries[i]))) {
  98.             char Buf[2000];
  99.             strcpy(Buf, Boundaries[i]);
  100.             strcat(Buf, "--\n");
  101.             if (!strcmp(Buf, s)) *BoundaryCt = i;
  102.             return(1);
  103.         }
  104.     }
  105.     return(0);
  106. }
  107.  
  108. from64(infile, outfile, boundaries, boundaryct) 
  109. FILE *infile, *outfile;
  110. char **boundaries;
  111. int *boundaryct;
  112. {
  113.     int c1, c2, c3, c4;
  114.     int newline = 1, DataDone = 0;
  115.  
  116.     while ((c1 = getc(infile)) != EOF) {
  117.         if (isspace(c1)) {
  118.             if (c1 == '\n') {
  119.                 newline = 1;
  120.             } else {
  121.                 newline = 0;
  122.             }
  123.             continue;
  124.         }
  125.         if (newline && boundaries && c1 == '-') {
  126.             char Buf[200];
  127.             /* a dash is NOT base 64, so all bets are off if NOT a boundary */
  128.             ungetc(c1, infile);
  129.             fgets(Buf, sizeof(Buf), infile);
  130.             if (boundaries
  131.                  && (Buf[0] == '-')
  132.                  && (Buf[1] == '-')
  133.                  && PendingBoundary(Buf, boundaries, boundaryct)) {
  134.                 return;
  135.             }
  136.             fprintf(stderr, "Ignoring unrecognized boundary line: %s\n", Buf);
  137.             continue;
  138.         }
  139.         if (DataDone) continue;
  140.         newline = 0;
  141.         do {
  142.             c2 = getc(infile);
  143.         } while (c2 != EOF && isspace(c2));
  144.         do {
  145.             c3 = getc(infile);
  146.         } while (c3 != EOF && isspace(c3));
  147.         do {
  148.             c4 = getc(infile);
  149.         } while (c4 != EOF && isspace(c4));
  150.         if (c2 == EOF || c3 == EOF || c4 == EOF) {
  151.             fprintf(stderr, "Premature EOF!\n");
  152.             return;
  153.         }
  154.         if (c1 == '=' || c2 == '=') {
  155.             DataDone=1;
  156.             continue;
  157.         }
  158.         c1 = char64(c1);
  159.         c2 = char64(c2);
  160.         putc(((c1<<2) | ((c2&0x30)>>4)), outfile);
  161.         if (c3 == '=') {
  162.             DataDone = 1;
  163.         } else {
  164.             c3 = char64(c3);
  165.             putc((((c2&0XF) << 4) | ((c3&0x3C) >> 2)), outfile);
  166.             if (c4 == '=') {
  167.                 DataDone = 1;
  168.             } else {
  169.                 c4 = char64(c4);
  170.                 putc((((c3&0x03) <<6) | c4), outfile);
  171.             }
  172.         }
  173.     }
  174. }
  175.  
  176. static char basis_hex[] = "0123456789ABCDEF";
  177. static char index_hex[128] = {
  178.     -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
  179.     -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
  180.     -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
  181.      0, 1, 2, 3,  4, 5, 6, 7,  8, 9,-1,-1, -1,-1,-1,-1,
  182.     -1,10,11,12, 13,14,15,-1, -1,-1,-1,-1, -1,-1,-1,-1,
  183.     -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
  184.     -1,10,11,12, 13,14,15,-1, -1,-1,-1,-1, -1,-1,-1,-1,
  185.     -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1
  186. };
  187.  
  188. #define hexchar(c)  (((c) < 0 || (c) > 127) ? -1 : index_hex[(c)])
  189.  
  190. /*
  191. hexchar(c)
  192. char c;
  193. {
  194.     char *s;
  195.     if (islower(c)) c = toupper(c);
  196.     s = (char *) index(basis_hex, c);
  197.     if (s) return(s-basis_hex);
  198.     return(-1);
  199. }
  200. */
  201.  
  202. toqp(infile, outfile) 
  203. FILE *infile, *outfile;
  204. {
  205.     int c, ct=0, prevc=255;
  206.     while ((c = getc(infile)) != EOF) {
  207.         if ((c < 32 && (c != '\n' && c != '\t'))
  208.              || (c == '=')
  209.              || (c >= 127)
  210.              /* Following line is to avoid single periods alone on lines,
  211.                which messes up some dumb smtp implementations, sigh... */
  212.              || (ct == 0 && c == '.')) {
  213.             putc('=', outfile);
  214.             putc(basis_hex[c>>4], outfile);
  215.             putc(basis_hex[c&0xF], outfile);
  216.             ct += 3;
  217.             prevc = 'A'; /* close enough */
  218.         } else if (c == '\n') {
  219.             if (prevc == ' ' || prevc == '\t') {
  220.                 putc('=', outfile); /* soft & hard lines */
  221.                 putc(c, outfile);
  222.             }
  223.             putc(c, outfile);
  224.             ct = 0;
  225.             prevc = c;
  226.         } else {
  227.             putc(c, outfile);
  228.             ++ct;
  229.             prevc = c;
  230.         }
  231.         if (ct > 72) {
  232.             putc('=', outfile);
  233.             putc('\n', outfile);
  234.             ct = 0;
  235.             prevc = '\n';
  236.         }
  237.     }
  238.     if (ct) {
  239.         putc('=', outfile);
  240.         putc('\n', outfile);
  241.     }
  242. }
  243.  
  244. fromqp(infile, outfile, boundaries, boundaryct) 
  245. FILE *infile, *outfile;
  246. char **boundaries;
  247. int *boundaryct;
  248. {
  249.     int c1, c2, sawnewline = 1;
  250.  
  251.     while ((c1 = getc(infile)) != EOF) {
  252.         if (sawnewline && boundaries && (c1 == '-')) {
  253.             char Buf[200], *s;
  254.  
  255.             ungetc(c1, infile);
  256.             fgets(Buf, sizeof(Buf), infile);
  257.             if (boundaries
  258.                  && (Buf[0] == '-')
  259.                  && (Buf[1] == '-')
  260.                  && PendingBoundary(Buf, boundaries, boundaryct)) {
  261.                 return;
  262.             }
  263.             /* Not a boundary, now we must treat THIS line as q-p, sigh */
  264.             for (s=Buf; *s; ++s) {
  265.                 if (*s == '=') {
  266.                     if (!*++s) break;
  267.                     if (*s == '\n') {
  268.                         /* ignore it */
  269.                         sawnewline = 1;
  270.                     } else {
  271.                         c1 = hexchar(*s);
  272.                         if (!*++s) break;
  273.                         c2 = hexchar(*s);
  274.                         putc(c1<<4 | c2, outfile);
  275.                     }
  276.                 } else {
  277.                     putc(*s, outfile);
  278.                 }
  279.             }
  280.         } else {
  281.             sawnewline = (c1 == '\n') ? 1 : 0;
  282.             if (c1 == '=') {
  283.                 c1 = getc(infile);
  284.                 if (c1 == '\n') {
  285.                     /* ignore it */
  286.                     sawnewline = 1;
  287.                 } else {
  288.                     c2 = getc(infile);
  289.                     c1 = hexchar(c1);
  290.                     c2 = hexchar(c2);
  291.                     putc(c1<<4 | c2, outfile);
  292.                     if (c2 == '\n') sawnewline = 1;
  293.                 }
  294.             } else {
  295.                 putc(c1, outfile);
  296.             }
  297.         }
  298.     }
  299. }
  300.  
  301.